关于android签名及渠道打包

为什么要签名

  • 开发Android的人这么多,完全有可能大家都把类名,包名起成了一个同样的名字,这时候如何区分?签名这时候就是起区分作用的。

  • 由于开发商可能通过使用相同的Package Name来混淆替换已经安装的程序,签名可以保证相当名字,但是签名不同的包不被替换。

  • APK如果使用一个key签名,发布时另一个key签名的文件将无法安装或覆盖老的版本,这样可以防止你已安装的应用被恶意的第三方覆盖或替换掉。这样签名其实也是开发者的身份标识。交易中抵赖等事情发生时,签名可以防止抵赖的发生。

签名的注意事项

  • Android系统要求所有的程序经过数字签名才能安装,如果没有可用的数字签名,系统将不许安装运行此程序。不管是模拟器还是真实手机。因此,在设备或者是模拟器上运行调试程序之前,必须为应用程序设置数字签名。

  • Android签名的数字证书不需要权威机构来认证,是开发者自己产生的数字证书,即所谓的自签名。数字证书用来标识应用程序的作者和在应用程序之间建立信任关系,而不是用来决定最终用户可以安装哪些应用程序。系统仅仅会在安装的时候测试签名证书的有效期,如果应用程序的签名是在安装之后才到期,那么应用程序仍然可以正常启用。

  • 可以使用标准工具-Keytool and Jarsigner-生成密钥,来签名应用程序的.apk文件。签名后需使用zipalign优化程序。

  • 模拟器开发环境,开发时通过ADB接口上传的程序会先自动被签有Debug权限,然后才传递到模拟器。Eclipse菜单的Window -> Preferences -> Android –> Build 下显示的是我们默认的调试用的签名数字证书。

  • 正式发布一个Android应用时,必须使用一个合适的私钥生成的数字证书来给程序签名,不能使用ADT插件或者ANT工具生成的调试证书来发布。

签名的步骤

方法一:利用命令行

  1. 创建key

    生成keystore (如已有可直接利用)
    按照下面的命令行 在JAVA_HOME\bin>目录下,输入:keytool -genkey -alias android.keystore -keyalg RSA -validity 10000 -keystore android.keystore

    • 参数意义:

      -genkey 产生密钥

      -alias 别名

      -keyalg RSA 使用RSA算法对签名加密

      -validity 10000 有效期限10000天

      -keystore 密钥名

  2. 使用步骤1中产生的key对apk签名

    按照下面的命令行 在JAVA_HOME\bin>目录下,输入:jarsigner -verbose -keystore android.keystore -signedjar demo_signed.apk demo.apk android.keystore

注意事项

android工程的bin目录下的demo.apk默认是已经使用debug用户签名的,所以不能使用上述步骤对此文件再次签名。正确步骤应该是:在工程点击右键->Android Tools-Export Unsigned Application Package导出的apk采用上述步骤签名。

方法二:使用Eclipse导出带签名的apk

选中project,单击右键选择Android Tools—>Export Signed Application Package,按提示完成即可(没有key的先创建)

签名之后,用zipalign(压缩对齐)优化你的APK文件。

未签名的apk不能使用,也不能优化。签名之后的apk谷歌推荐使用zipalign.exe(位于android-sdk-windows ools目录下)工具对其优化:
在JAVA_HOME\bin>目录下zipalign -v 4 demo_signed.apk final.apk
如上,zipalign能够使apk文件中未压缩的数据在4个字节边界上对齐(4个字节是一个性能很好的值),这样android系统就可以使用mmap()(请自行查阅这个函数的用途)函数读取文件,可以在读取资源上获得较高的性能

PS:

  1. 在4个字节边界上对齐的意思就是,一般来说,是指编译器吧4个字节作为一个单位来进行读取的结果,这样的话,CPU能够对变量进行高效、快速的访问(较之前不对齐)。

  2. 对齐的根源:android系统中的Davlik虚拟机使用自己专有的格式DEX,DEX的结构是紧凑的,为了让运行时的性能更好,可以进一步用”对齐”进一步优化,但是大小一般会有所增加。

渠道打包

为什么需要在应用程序中增加渠道信息?

Android应用的发布需要面对各种各样的市场,我们称之为渠道。有的时候,我们需要知道应用是从哪个渠道下载的。比如,我们可能需要统计哪些市场带来的用户量比较大。再比如,我们可能有一些盈利需要和具体的渠道进行分成。这些都是统计渠道的信息。

一般如何在应用中加入渠道信息?

为了统计渠道信息,就不得不在程序的某个地方加入渠道的信息,然后针对不同的渠道打不同的包。一般可以在Manifest文件中加入渠道编号,而不直接写在代码中。这样做的好处是,可以针对不同渠道,自动化去修改Manifest文件中的渠道编号,然后自动为该渠道打包。
Manifest文件支持Meta Data标签,建议使用这种自定义标签。例如下面的文件片段。

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    android:versionCode="X"
    android:versionName="X.X.X"
    package="com.XXX">
    ……
    <application android:icon="@drawable/icon"
    android:label="@string/app_name">
    ……
    <meta-data android:name="CHANNEL" android:value="C_001" />
    </application>
</manifest>

在这段代码示例中,我们在Application节点下增加了一个meta-data标签,名称是CHANNEL,值是C_001,是我们规定的一个渠道的编号。为不同的渠道打包,就要手工或者自动化修改C_001成为C_002、C_003等等其它我们定义的渠道编号,然后再打不同的包。

如何自动化打包过程?

在这里介绍一款开源的打包工具 友盟渠道打包工具 (windows .net 4.0) 目前只支持windows版本

github地址:https://github.com/umeng/umeng-muti-channel-build-tool

现在最新版本号为:V3.2,本次更新最大的改变是放弃了 V2.x 版本中通过 Apktool 反编译apk文件打包的方式,这种打包方式会对开发的apk文件做出大幅度的修改,可能会产生许多不兼容的问题,比如对jar包中包含资源的情况无法支持,对包含 .so 文件的apk兼容性也不好,而且在打包时 AndroidManifest.xml 文件中的特殊标签会丢失。为了解决这些问题减少对开发者apk文件的修改, 我们决定放弃这种方式,而采用直接编辑二进制的AndroidManifest.xml 文件的方式。这种方式只会修改 AndroidManifest.xml 文件,对于apk包中的资源文件和代码文件都不会做任何改变。如果打包不成功,生成的apk文件有问题,在测试阶段也可以快速发现,因为修改只会影响AndroidManifest.xml 相关的少量的设置。

编辑渠道信息注意事项

  1. 编辑渠道完成后按Enter确认
  2. 常用渠道可以自行配置,模板地址:\UmengTools(Green)V3.2\V3.2\projects\template.xml(先配置好后再打开友盟打包工具)
  3. 左下角配置文件可以自行填写,工具会自动保存你这次打包的信息(签名及渠道信息),下次可以在主页直接切换

工具界面:

umeng_package_too